package FrameWork.Event;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class TriggerManager {

    private static Logger logger = Logger.getLogger(TriggerManager.class);
    //事件类型到事件实例
    private static final Map<Class<? extends Trigger>, Trigger> triggerMap = new ConcurrentHashMap<>();
    //事件类型到事件处理器类型，用于类型检查
    private static final Map<Class<? extends Trigger>, Class<? extends EventHandler>> handlerTypeOfTrigger = new HashMap<>();


    /**
     *
     * @param clazz 事件类型
     * @param <T> 继承Trigger的类型
     * @return 对应事件
     */
    @SuppressWarnings("unchecked")
    public static <T extends Trigger> T getTrigger(final Class<T> clazz) {
        if (!triggerMap.containsKey(clazz)){
            logger.debug(clazz+"没有注册");
            throw new IllegalArgumentException(clazz+"没有注册");
        }
        return (T) triggerMap.get(clazz);
    }



    /**
     * 注册事件，在Spring容器初始化的时候进行注册事件{@link TriggerManagerConfigure#init()}
     * @param trigger
     */
    static void registerTrigger(final Trigger trigger) {
        logger.debug("注册事件" + trigger.getClass().getName());
        Class<? extends Trigger> clazz = trigger.getClass();
        Class<? extends EventHandler> type = TriggerReflectUtil.getEventHandlerType(clazz);
        if (triggerMap.containsKey(clazz)) {
            logger.error(clazz.getName() + "重复注册");
            return;
        }
        if (type == null) {
            logger.error("注册失败"+clazz.getName() + "没有指定EventHandler的类型");
            return;
        }
        triggerMap.put(clazz, trigger);
        handlerTypeOfTrigger.put(clazz, type);
    }

    /**
     * 注册事件处理器，在Spring容器初始化的时候进行注册{@link TriggerManagerConfigure#init()}
     * @param triggerType 触发器类型
     * @param handler 对应的事件处理器，在注册前会进行类型检查
     */
    @SuppressWarnings("unchecked")
    static void safeRegisterEventHandler(final Class<? extends Trigger> triggerType,final EventHandler handler) {
        Trigger trigger = triggerMap.get(triggerType);
        Class<? extends EventHandler> handlerType = handlerTypeOfTrigger.get(triggerType);
        //对类型进行检查
        if (handlerType.isAssignableFrom(handler.getClass())) {
            trigger.registerHandler(handler);
            logger.debug(handler.getClass().getName()+"注册到"+trigger.getClass().getName());
        }
    }


}
